In the field of software engineering, "instrumentation" refers to a set of techniques used to characterize or verify the behavior of a program. For example, instrumentation may be used to measure the runtime of selected parts of a program. Instrumentation may also be used to determine if, or how often, a particular procedure is called within a program.
The simplest instrumentation technique involves changes that are made within the source code from which the program is compiled. For example, print statements may be added to indicate that a program has reached a particular location and to print out diagnostic or statistical information. Code may also be added to time the execution of a program or program segments. Generally, this type of instrumentation is both widely used and problematic. The ease with which source code may be added accounts for the widespread use of this technique. Unfortunately, the addition of source code changes the characteristics of the program itself. These changes may be subtle, such as changes in program runtime, or they may be profound, such as inadvertent program incorrectness. In either case, the effectiveness of instrumentation through addition of source code may be limited.
A second technique for instrumentation uses the system compilation tools (compiler, assembly, linker and system libraries) to produce specialized instrumented executables. These instrumented executables include machine code that gathers statistics during execution of the program. For example, statistics may be gathered that include a count of the number of times each procedure within a program is called during a particular execution. Alternatively, statistics may be gathered that include the execution times of some or all of the procedures called during a particular execution of a program.
This second technique for software instrumentation has proven to be an effective tool for gathering needed data. Unfortunately, the runtime characteristics of the instrumented executable will, by necessity, vary from the runtime characteristics of a standard executable. Additionally, the use of an instrumented executable implies that, if a different type of instrumentation is required or becomes desirable, a different instrumented executable will have to be produced by the system compilation tools. In many cases this involves recompiling, re-assembling and re-linking the program's source modules. For large programs, this may require a substantial amount of time.
It is also generally the case that most system compilation tools offer only a limited range of predefined instrumentation methods. Thus, if a different type of instrumentation is required, it is often necessary to change one or more of the system compilation tools. In many cases, this may be impractical.
The present invention is directed at dynamically linked programming environments. More specifically, in dynamically linked programming environments, such as the Solaris.RTM. operating system of Sun Microsystems Inc., each program may include references to "objects" (objects include procedures and functions as well as global data objects) that are not resolved until the program's execution. As part of program execution, each unresolved reference is replaced with the address of the corresponding object. The process of replacing unresolved references is performed by a program known as a runtime linker. Generally, the unresolved references in a program can be replaced as part of the program's invocation. Alternatively, certain unresolved references (namely, those corresponding to procedures and functions) are replaced one by one as they are encountered during program execution. The latter method is generally referred to as "lazy binding," and offers the advantage of resolving only those references that are actually reached during program execution.